﻿using LYR_RPA.models.entity;
using LYR_RPA.models.events;
using LYR_RPA.Properties;
using LYR_RPA.utils;
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LYR_RPA.service
{
    public class WebSocketClient
    {
        private static WebSocketClient instance;
        private ClientWebSocket webSocket; // WebSocket 实例
        public bool isConnected = false; // 是否成功连接到 WebSocket 服务器
        private static int reconnectInterval = 1000; // 重新连接时的间隔时间，默认为 1000ms
        private readonly int maxReconnectInterval = 60000; // 重新连接时的最大间隔时，默认为 60000ms

        private string address;
        private string port;
        public bool isRetry = true;

        // 定义与 WebSocket 事件关联的事件处理程序
        public static event EventHandler<Receive> MessageReceived; // 当接收到消息时发生

        private MessageHandle messageHandle;
        private CancellationTokenSource cts;

        public static string token = "";

        private WebSocketClient() { }

        public static WebSocketClient Instance => instance ?? (instance = new WebSocketClient());

        // 连接 WebSocket 服务器
        public async Task Connect()
        {
            isRetry = true;

            // 关闭之前的连接
            if (isConnected)
            {
                await CloseWebSocketAsync();
            }

            // 读取新的地址和端口
            address = Settings.Default.ServerAddress;
            port = Settings.Default.Port;

            Console.WriteLine(Settings.Default.ID);
            

            try
            {
                // 创建新的 WebSocket 实例
                webSocket = new ClientWebSocket();
                // 添加自定义请求头
                Console.WriteLine(token);
                /*webSocket.Options.SetRequestHeader("Connection", "Upgrade");
                webSocket.Options.SetRequestHeader("Upgrade", "websocket");*/
                webSocket.Options.SetRequestHeader("Tenant-Id", "1");
                webSocket.Options.SetRequestHeader("Authorization", "Bearer " + token);
                
                // 构建新的 WebSocket 地址
                var uri = new Uri($"ws://{address}:48091/infra/ws?identification=" + (string.IsNullOrEmpty(Settings.Default.ID) ? "" : Settings.Default.ID));
                Console.WriteLine(uri);
                // 尝试连接
                await webSocket.ConnectAsync(uri, CancellationToken.None);
                isConnected = true;

                // 创建 CancellationTokenSource
                cts = new CancellationTokenSource();
                // 开始接收消息
                _ = ReceiveMessages(cts.Token);
            }
            catch (Exception ex)
            {
                Console.WriteLine("连接失败: " + ex);
                isConnected = false; // 确保连接失败时状态更新
            }
        }

        // 返回当前是否已连接到 WebSocket 服务器
        public bool IsConnected() => IsWebSocketConnected();

        // 判断 WebSocket 是否连接
        private bool IsWebSocketConnected() => webSocket != null && webSocket.State == WebSocketState.Open;

        // 关闭 WebSocket 连接
        public async Task CloseWebSocketAsync()
        {
            if (IsWebSocketConnected())
            {
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
                isConnected = false;
                Console.WriteLine("连接关闭");
                // 取消接收消息
                cts.Cancel();
                cts.Dispose();
            }
        }

        // 异步发送消息
        public async Task SendMessage(string message)
        {
            if (IsWebSocketConnected())
            {
                var bytes = Encoding.UTF8.GetBytes(message);
                var buffer = new ArraySegment<byte>(bytes);
                await webSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
            }
            else
            {
                Console.WriteLine("发送失败");
            }
        }

        // 处理接收到的消息
        private async Task ReceiveMessages(CancellationToken cancellationToken)
        {
            var buffer = new ArraySegment<byte>(new byte[1024]);

            try
            {
                while (isConnected && !cancellationToken.IsCancellationRequested)
                {
                    WebSocketReceiveResult result = await webSocket.ReceiveAsync(buffer, cancellationToken);
                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        await CloseWebSocketAsync();
                    }
                    else
                    {
                        string message = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
                        
                        if (messageHandle == null)
                        {
                            messageHandle = new MessageHandle();
                        }
                        // 将消息转换并发送到订阅事件中
                        Receive receive = JSONUtils.StringToObject<Receive>(message);
                        MessageReceived?.Invoke(this, receive);
                    }
                }
            }
            catch (WebSocketException ex)
            {
                Console.WriteLine("WebSocket 错误: " + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("错误: " + ex.Message);
            }
        }
    }
}
